Vous devez activer Javascript pour accéder à ce site
 

Semaine

RECHERCHE

Modèles de programmation

Il y a plusieurs façons de traiter du XML. Chaque méthode a ses avantages et ses inconvénients. Bien que ce module s'intéresse surtout à l'approche DOM, il est important de connaître l'ensemble des méthodologies possibles et d'avoir une idée des forces et faiblesses relatives de chacune.

Traitement du XML comme du texte

Un fichier XML est d'abord un fichier texte. Comme certains langages, tel Java, savent bien traiter les fichiers en format texte, ils peuvent directement traiter le XML. En fait, du moment où nous utilisons un éditeur de texte pour écrire du XML, c'est exactement ce que nous faisons : nous utilisons, comme outil XML, un programme prévu pour traiter du texte.

Par exemple, nous pouvons produire du XML à partir d'un programme Java avec des instructions comme celles qui suivent :

 int montant = 10;
 String nom= "Gérard Beauford";
 System.out.println("<?xml version="1.0" ?> <facture><montant>"+montant
 +"</montant><nom>"+nom+"</nom></facture>");

Cependant, comment savoir si le XML produit est bien formé? Dans l'exemple précédent, le document XML affiché à l'écran avec l'instruction « System.out.println » ne sera pas du XML bien formé. Pourquoi? Il y a un accent dans le nom et la plupart des environnement de commande n'utilisent pas la norme UTF-8. En principe, il est possible d'écrire un programme Java qui génère du XML bien formé la plupart du temps; mais, une fois de temps en temps, il se produira une erreur dans le XML. Cette erreur pourrait toutefois être suffisamment sérieuse et entraîner un bogue important : Mozilla Firefox refusera d'afficher du XML qui n'est pas bien formé. Pour cette raison, il est préférable, quand cela en vaut la peine, d'utiliser des librairies ou outils dédiés au XML pour une meilleure productivité.

De la même façon, lire du XML sans avoir recours à des librairies peut être difficile; par exemple, supposons qu'il faille écrire un programme Java sans utiliser des librairies capables d'extraire le nom et le montant du fichier XML suivant :

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <facture> <montant>432</montant> <nom>Gérard Beauford</nom></facture>

Un tel programme peut être relativement difficile à écrire. Nous pouvons toutefois bien y arriver avec les expressions régulières (voir le paquetage « java.util.regex » en Java), mais dans le cas de fichiers XML plus complexes, le programme risque de devenir long et fastidieux.

Illustrons comment les choses peuvent se corser davantage en étudiant l'exemple suivant :

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <!DOCTYPE facture [ <!ELEMENT facture (montant, nom)> <!ELEMENT montant (#PCDATA)> <!ELEMENT nom (#PCDATA)> <!ATTLIST nom surnom CDATA "Joe"> ]> <facture><montant>432</montant><nom>Gérard Beauford</nom></facture>

Supposons maintenant que vous deviez écrire un programme Java pour déterminer la valeur de l'attribut « surnom » de l'élément « nom » de ce document XML. Nous constatons qu'il faut traiter non seulement le XML, mais aussi la DTD. Et nous savons que les DTD sont le plus souvent externes, ce qui rend le problème encore plus difficile. Supporter l'ensemble des normes XML devient rapidement très fastidieux : pensons aux entités, déclarations XML, et ainsi de suite.

Donc, le traitement du XML en tant que texte est une méthode qui, sans être inappropriée, a ses limites.

Traitement événementiel

Le traitement événementiel est une approche très simple pour traiter le XML, mais qui peut être difficile pour le programmeur. En fait, une API, souvent l'API SAX, est utilisée pour lire le XML en séquence. Une alternative à SAX est XNI (Xerces Native Interface). Chaque fois qu'une nouvelle balise ou tout autre élément significatif (instruction XML, contenu XML, etc.) est rencontré, un « événement » est généré. C'est le même type de traitement qui est utilisé pour gérer l'interface graphique avec boutons, fenêtres, etc.; dans ce type de traitement toutefois, l'événement « presse le bouton » est plutôt du type « nouvel élément rencontré ».

Par exemple, avec le document XML qui suit...

<facture><montant>432</montant><nom>Maman</nom></facture>

nous aurons les « événements » suivants (avec la librairie Sax) :

  1. Début du document
  2. Début d'un élément « facture »
  3. Début d'un élément « montant »
  4. Texte « 432 »
  5. Fin d'un élément « montant »
  6. Début d'un élément « nom »
  7. Texte « Maman »
  8. Fin d'un élément « nom »
  9. Fin d'un élément « facture »
  10. Fin du document

La programmation événementielle peut être plus facile et plus fiable que le traitement du XML en tant que texte parce qu'au lieu de traiter chaque caractère, nous n'avons qu'à traiter ce qui est significatif pour le XML (balises de début et de fin, texte, etc.). Par exemple, les commentaires en XML seront automatiquement reconnus par un parseur événementiel. En fait, le parseur peut parfaitement omettre de générer un événement quand un commentaire est rencontré : c'est pourquoi les commentaires ne doivent jamais contenir des informations importantes. Les valeurs d'attributs par défaut, comme « surnom » dans l'exemple précédent, peuvent être traitées automatiquement.

Le traitement événementiel implique quand même beaucoup de travail de la part du programmeur, particulièrement s'il doit prendre en compte plusieurs informations dans le document. Par exemple, s'il est nécessaire de connaître le contenu de tous les éléments du document XML, il faut enregistrer toutes ces informations, car le traitement événementiel ne permet pas les retours en arrière : le fichier est lu en séquence et nous devons faire le reste.

Il y a des cas où le traitement événementiel est la meilleure solution. Lorsque nous devons traiter des fichiers XML très lourds, faisant plusieurs Mo, ou que l'on travaille sur des machines avec peu de mémoire (comme un téléphone cellulaire), ce type de traitement permet de faire une utilisation judicieuse de la mémoire vive. Un cas intéressant est celui où seuls quelques éléments d'un document XML nous intéressent. Par exemple, nous cherchons la valeur des éléments « nom » : le traitement événementiel permet de parcourir tout le document, mais de ne retenir que l'information voulue.

En général, nous pouvons dire que la programmation événementielle du XML est réservée à des cas particuliers, tels les documents lourds, et aux experts.

L'utilisation de SAX2 est fort simple à la base comme le montre le programme MonApplicationSAX. Il suffit de créer une classe dérivée de org.xml.sax.helpers.DefaultHandler où l'on surcharge des méthodes comme « startElement », « endElement » et « characters » qui nous permettent de gérer les événements « début d'un élément », « fin d'un élément » et « nœud de texte » respectivement. On peut aussi gérer d'autres événements comme le début du document (méthode « startDocument ») et sa fin (méthode « endDocument »). Ce type de programmation orientée-objet correspond au patron de l'observateur : on construit une classe qui est chargée de recevoir les différents événements et d'y réagir. Même les programmeurs expérimentés utilisent peu souvent ce type de patron.

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
 
 /**
 * INF 6450
 * Daniel Lemire
 */
 public class MonApplicationSAX extends DefaultHandler {
     /**
     * Événement correspondant au début d'un élément
     */
     public void startElement (String uri, String name, String qName, 
          Attributes atts)  {
        if(uri.length()&gt;0)
         System.out.println("Début de l'élément "+uri+":"+qName);
        else 
         System.out.println("Début de l'élément "+name);
     }
 
     /**
     * Événement correspondant à la fin d'un élément
     */
     public void endElement (String uri, String name, String qName)   {
        if(uri.length()&gt;0)
         System.out.println("Fin de l'élément "+uri+":"+qName);
        else 
         System.out.println("Fin de l'élément "+name);
 
     }
     
     /**
     * Ici on traite l'événement correspondant à un noeud de texte
     */
     public void characters (char charac[], int debut, int longueur) {
       for (int i = debut; i &lt; longueur+debut; ++i) 
        System.out.print(charac[i]);
       System.out.println();
     }
 
     /**
     * on traite un fichier offert en ligne de commande.
     * Utilisation: java MonApplicationSAX nomdufichier.xml
     */
     public static void main (String args[]) throws Exception {
         XMLReader xr = XMLReaderFactory.createXMLReader();
         xr.setContentHandler(new MonApplicationSAX());
         xr.parse(new InputSource(new FileReader(args[0])));
     }
 
 }

Traitement avec itérateurs

Le traitement événementiel n'est pas très intuitif. Par contre, la plupart des programmeurs Java connaissent le traitement itératif. Voici un exemple très simple de programmation avec un itérateur :

import java.util.*; public class myvec { public static void main(String[] arg) { Vector<String> v= new Vector<String>(); v.add("parent"); v.add("enfant"); Iterator i = v.iterator(); while(i.hasNext()) System.out.println(i.next()); } }

Au lieu de créer une classe qui attend passivement de recevoir des événements, on fait une simple boucle. La Streaming API for XML (StAX) permet de faire un peu la même chose avec du XML. Voici un exemple, observez bien la présence d'une seule boucle et l'absence de plusieurs méthodes :

// ce programme nécessite l'installation d'une // librairie StAX // voir http://dev2dev.bea.com/xml/stax.html // import javax.xml.stream.*; import java.net.*; import java.io.*; public class staxex { public static void main(String[] args) { String input = args[0]; try { URL u = new URL(input); InputStream in = u.openStream(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in); for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) { switch (event) { case XMLStreamConstants.START_ELEMENT: System.out.println(parser.getLocalName()); break; case XMLStreamConstants.END_ELEMENT: System.out.println(parser.getLocalName()); break; case XMLStreamConstants.CDATA: System.out.print(parser.getText()); break; } } parser.close(); } catch (XMLStreamException ex) { System.out.println(ex); } catch (IOException ex) { System.out.println(ex); } } }

StAX est une norme Java officielle (JSR 173). La librairie open source Woodstox offre une implémentation de l'API StAX.

Traitement avec modèle en arbre

Un document XML peut être vu comme un arbre avec un élément-racine contenant lui-même des éléments, qui eux-mêmes contiennent des éléments, et ainsi de suite. Ainsi, en utilisant le traitement événementiel par exemple, une librairie peut d'abord lire le document XML et créer un modèle en arbre. Le modèle en arbre XML le plus connu et qui sert de référence est le Document Object Model (DOM). Il est facile de trouver des librairies qui supportent le DOM ou une variante. Nous traiterons du DOM dans un prochain texte.

Ainsi, étant donné le document XML suivant...

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <!DOCTYPE facture [ <!ELEMENT facture (montant, nom)> <!ELEMENT montant (#PCDATA)> <!ELEMENT nom (#PCDATA)> <!ATTLIST nom surnom CDATA "Joe"> ]> <facture><montant>432</montant> <nom>Gérard Beauford</nom></facture>

un modèle en arbre aura comme objet-racine un objet représentant le document lui-même ayant comme enfant l'élément « facture ». Cet objet aura lui-même une liste d'enfants, c'est-à-dire deux objets représentant les éléments « montant » et « nom ». La valeur d'attribut de « surnom » se trouvera dans l'objet représentant l'élément « nom ».

De façon simpliste, nous pouvons représenter le document XML précédent avec le diagramme en arbre suivant :

 
         Document - déclaration de type
           |
         facture 
        |     |
    montant   nom (surnom="Joe")
      |           |
    "432"     "Gérard Beauford"
 

La programmation avec des modèles en arbre n'est pas toujours facile. Il y a un grand nombre d'objets à manipuler (un pour chaque élément de l'arbre) et donc beaucoup d'appels de fonctions. De plus, ce type de programmation exige beaucoup de mémoire parce que, généralement, le parseur va d'abord visiter le document en entier, le transformer en objets, puis tout stocker en mémoire.

D'un autre côté, ce type de programmation (avec modèle en arbre) est sans doute l'une des façons les plus conviviales de traiter de petits fichiers XML à partir d'un langage orienté-objet comme Java. Il est relativement facile d'apprendre à écrire des programmes en Java pour traiter le XML, en utilisant le  DOM.

De la même façon, à partir d'un modèle en arbre, nous pouvons produire un document XML. Si nous utilisons une bonne librairie, nous sommes certains que le document XML généré sera bien formé et conforme à notre intention. Il faut par contre bien comprendre que le même modèle en arbre peut correspondre à plusieurs fichiers XML différents. Dans l'exemple précédent, il est possible qu'une librairie, qui a comme paramètre l'arbre que nous avons dessiné, génère un fichier XML comme celui-ci :

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <facture><montant>432</montant> <nom surnom="Joe">Gérard Beauford</nom></facture>

Transformations

Le XSLT est une autre façon de traiter le XML par la programmation. Dans les cas les plus simples, c'est probablement le meilleur outil. Cependant, pour un traitement plus complexe, avec intégration dans un système d'information, il ne suffira généralement pas. Par exemple, le XSLT n'est pas conçu pour aller chercher des informations dans une base de données et les transformer en XML bien formé.

XPath

Si nous devons extraire de l'information d'un document XML à partir d'un langage comme Java, il sera souvent plus simple d'utiliser une API qui supporte XPath. C'est le cas notamment du « SDK Java  ». Nous avons étudié les expressions XPath dans le module 3. Comme nous pouvons le voir avec l'exemple suivant, l'utilisation de XPath en Java requiert la création de plusieurs objets intermédiaires, ce qui n'est pas toujours très pratique. Le traitement XPath se fait sur un document chargé complètement en mémoire ce qui rend son application prohibitive sur de gros documents. Par contre, la syntaxe XPath est très expressive et peut éviter d'avoir à écrire de longs programmes Java.

/* on doit toujours importer ces deux paquetages: */ import javax.xml.parsers.*; import javax.xml.xpath.*; /* on doit construire une instance du document XML */ DocumentBuilderFactory dbfact = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbfact.newDocumentBuilder(); /* on peut traiter directement un URL */ Document document = builder.parse("http://www.mondomaine.com/monfichier.xml"); /* on construit un objet XPath */ XPathFactory fact = XPathFactory.newInstance(); XPath xpath = fact.newXPath(); /* finalement, on peut émettre sa requête XPath sur le document */ String title = xpath.evaluate("//nom/text()", document);

XML comme extension d'un langage

Tout comme les structures de données simples, tel que les tableaux, font souvent partie intégrante des langages de programmation, on choisit parfois d'intégrer le traitement du XML à même le langage. À titre d'exemple, EAX (ECMAScript for XML) est une norme qui définit une extension du langage ECMAScript pour le traitement du XML.

Avec ce type d'intégration, on peut définir un document XML directement dans le code comme dans cet exemple.

var sales = <sales vendor="John"> <item type="peas" price="4" quantity="6"/> <item type="carrot" price="3" quantity="10"/> <item type="chips" price="5" quantity="3"/> </sales>;

On peut aussi traiter les documents XML comme s'ils étaient des structures de données intégrées au langage, comme dans cet exemple.

for each( var price in sales..@price ) { alert( price ); }

EAX est supporté par les implémentations du ECMAScript de Firefox (JavaScript) et de Flash (ActionScript). Ce n'est pas le seul exemple d'intégration du XML à un langage.

Traitement par abstraction

Nous pouvons utiliser des outils et des librairies qui n'exigent aucune connaissance du XML, mais qui peuvent utiliser et générer du XML. Par exemple, la plupart des bases de données relationnelles permettent d'importer et d'exporter des données en XML, sans jamais devoir manipuler le XML directement. Une entreprise pourra écrire sa propre librairie de traitement du XML dans le contexte d'une application XML spécifique. Par exemple, imaginons une application XML pour les factures; nous pourrions écrire une fonction qui prend en paramètre le montant et la personne à qui est destinée la facture, et qui génère le XML, sans que nous n'ayons même à savoir ce qu'est le XML.

Sérialisation XML

Comme exemple de traitement par abstraction, on a la sérialisation XML des objets en Java. On définit le terme sérialisation XML comme la transformation d'un objet Java en un fichier XML de manière à ce qu'on puisse reconstuire l'objet par la suite. On peut utiliser la sérialisation pour rapidement enregistrer des informations sur le disque ou transmettre des objets vers un autre programme au travers un réseau. Par exemple, le programme Serialization.java enregistre sur le disque un fichier XML contenant la description complète d'un objet « java.lang.String ».

import java.beans.*; import java.io.*; /** * INF 6450 * Daniel Lemire */ public class Serialization { /** * Écrit l'objet en XML dans le fichier spécifié * (ce qu'on appelle une "sérialisation") */ public static void ecrireObjet(Object o, File f) throws IOException { XMLEncoder e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream(f))); e.writeObject(o); e.close(); } /** * Lit un objet "sérialisé" en XML dans le fichier spécifié */ public static Object lireObjet(File f) throws IOException { XMLDecoder e = new XMLDecoder( new BufferedInputStream( new FileInputStream(f))); Object o = e.readObject(); e.close(); return o; } /** * lit un fichier et l'affiche à l'écran! */ public static void affiche(File f) throws IOException { BufferedReader br = new BufferedReader(new FileReader(f)); String ligne; while((ligne = br.readLine()) != null) { System.out.println(ligne); } br.close(); } public static void main(String[] args) throws IOException { // je crée un objet java, dans ce cas, une chaîne de carac. String o = new String("Un objet java"); // je vais enregistrer le résultat dans un fichier XML File fichier = new File("test.xml"); ecrireObjet(o,fichier); affiche(fichier); Object lu = lireObjet(fichier); // ensuite, je vérifie que l'objet lu est bien identique // à l'objet écrit assert(lu.equals(o)); } }

Après l'exécution de ce programme, le contenu du fichier XML « test.xml » devrait ressembler à :

<?xml version="1.0" encoding="UTF-8"?> <java version="21" class="java.beans.XMLDecoder"> <string>Un objet java</string> </java>

On peut aussi utiliser la sérialisation avec ses propres objets à la condition qu'il s'agisse de « Beans » : tous les attributs de votre objet doivent être modifiés et lus par des méthodes qui débutent par « set » et « get » respectivement. Voici un exemple typique d'objet Bean qui peut facilement être sérialisé :

public class UneClasse { int x, y; public UneClasse() { } public int getX() {return x;} public int getY() {return y;} public void setX(int i) {x=i;} public void setY(int i) {y=i;} }

Voici un exemple de sérialisation XML de cet objet :

<?xml version="1.0" encoding="UTF-8"?> <java version="1.5.0_05" class="java.beans.XMLDecoder"> <object class="UneClasse"> <void property="x"> <int>1</int> </void> <void property="y"> <int>2</int> </void> </object> </java>

Il faut, bien entendu, que le programme qui lit vos objets sérialisés ait accès aux classes de vos objets.

Services web

Bien qu'il ne s'agisse pas d'une façon de traiter du XML, les services web font partie intégrante des méthodes de programmation utilisant le XML. La définition même de ce qu'est un service web peut varier, mais pour l'essentiel, il s'agit d'un service pouvant être utilisé au sein d'application logicielle. Le service est généralement accessible sur le web et répond aux requêtes par du XML. On peut transmettre les requêtes sous diverses formes : requêtes HTTP simples (GET), transmission de documents XML, etc. De nombreux sites web nous permettent d'utiliser des services web. Par exemple, Amazon, la librairie en ligne, vous permet d'utiliser un service web pour récupérer automatiquement les descriptions de produits. En principe, on peut combiner plusieurs services web pour composer des applications riches et originales, ou simplement pour ajouter une fonction particulière à un site web. Plusieurs protocoles peuvent être utilisés dont le Simple Object Access Protocol (SOAP) ou le Search/Retrieve via URL (SRU). On distingue généralement deux types de services web. Les services web « REST » tels que SRU se servent exclusivement du protocole HTTP et il est toujours possible de faire des requêtes en entrant simplement un URL dans un navigateur. Les services web REST font l'objet d'une spécification Java (Java Specification Request 311: Java API for RESTful Web Services). Les autres services web, dont ceux utilisant SOAP, exigent plutôt souvent que toutes les requêtes prennent la forme d'un fichier XML et ils ne tiennent pas compte particulièrement du protocole HTTP.

Le protocole HTTP (RFC 2616) est relativement simple. Toutes les requêtes se font du client vers le serveur et se distinguent par un URI et une méthode. Votre navigateur fait des requêtes GET à chaque fois que vous chargez une page. La plupart des formulaires que vous utilisez sur le web emploie la méthode POST. On choisit généralement une des méthodes suivantes :

Méthode Explication
GET Requête visant à obtenir la ressource (par exemple, un document XML) identifié par l'URI. Il s'agit du type de requête le plus utilisé: c'est celui utilisé généralement par les navigateurs pour charger les pages web. Une telle requête ne doit pas modifier l'état de la ressource.
POST Ajouter une nouvelle ressource (un document, une image, un texte) en lien avec l'URI ou annoter ou modifier une ressource existante. L'URI fourni ne sera pas l'URI de la ressource si une nouvelle ressource est créée.
PUT Créer ou remplacer une ressource ayant l'URI fourni. En général, les requêtes PUT sont utilisées pour remplacer les ressources (comme un fichier XML).
DELETE Supprimer une ressource (comme un document).

Les méthodes GET, PUT et DELETE sont idempotentes : on peut répéter la requête autant de fois qu'on le désire, et on obtiendra le même résultat qu'une seule requête. La méthode POST, par contre, n'est pas idempotente : sa répétition pourrait entraîner la création ou la modification de ressources. La méthode GET est sécuritaire : on peut l'employer sans crainte de créer ou de modifier une ressource.

Un exemple de service web REST simple, utilisant le protocole SRU, est offert par la librairie du congrès du gouvernement américain. À l'aide d'une simple requêtre prenant la forme d'un URL, on peut demander de recevoir un fichier XML décrivant n'importe quel livre connu de la librairie. Voici un exemple de code Java fonctionnel permettant de faire une telle requête :

import org.w3c.dom.*; import javax.xml.parsers.*; import javax.xml.xpath.*; public class example { public static void main(String[] args) throws Exception { String base = "http://z3950.loc.gov:7090/voyager?"; String autre = "operation=searchRetrieve&version=1.1&recordPacking=xml"; String autre2 = "&startRecord=1&maximumRecords=20&query="; String requete ="(dc.title=%22First Impressions of the New World%22) and (dc.creator all %22Trotter Isabella Strange%22)"; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); Document doc = parser.parse(base+autre+autre2+requete); Element racine = doc.getDocumentElement(); XPathFactory fact = XPathFactory.newInstance(); XPath xpath = fact.newXPath(); System.out.println("code: "+xpath.evaluate("//leader/text()", doc)); } }

En examinant le code, on peut voir qu'on cherche de l'information sur tous les livres ayant pour titre « First Impressions of the New World » et écrits par « Trotter Isabella Strange ». Le résultat de la requête SRU est plutôt incompréhensible dans ce cas précis. Il est surtout destiné aux spécialistes en bibliothéconomie :

<?xml version="1.0"?> <zs:searchRetrieveResponse xmlns:zs="http://www.loc.gov/zing/srw/"> <zs:version>1.1</zs:version><zs:numberOfRecords>1</zs:numberOfRecords> <zs:records><zs:record> <zs:recordSchema>info:srw/schema/1/marcxml-v1.1</zs:recordSchema> <zs:recordPacking>xml</zs:recordPacking><zs:recordData><record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01007cam a2200265u 4500</leader> <controlfield tag="001">8662129</controlfield> <controlfield tag="005">20011206111958.0</controlfield> <controlfield tag="008">830108s1859 enkb a 000 0 eng </controlfield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="9">(DLC) 02002686</subfield> </datafield> <datafield tag="906" ind1=" " ind2=" "> <subfield code="a">0</subfield> <subfield code="b">cbc</subfield> <subfield code="c">premunv</subfield> <subfield code="d">u</subfield> <subfield code="e">ncip</subfield> <subfield code="f">19</subfield> <subfield code="g">y-gencatlg</subfield> </datafield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 02002686 </subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">DLC</subfield> <subfield code="c">CarP</subfield> <subfield code="d">DLC</subfield> </datafield> <datafield tag="043" ind1=" " ind2=" "> <subfield code="a">n-cn---</subfield> <subfield code="a">n-us---</subfield> </datafield> <datafield tag="050" ind1="1" ind2="0"> <subfield code="a">E166</subfield> <subfield code="b">.T85</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">Microfilm 32043 E</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">[Trotter, Isabella (Strange)],</subfield> <subfield code="d">1816-1878. [from old catalog]</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">First impressions of the New world on two travellers from the Old, in the autumn of 1858.</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">London,</subfield> <subfield code="b">Longman, Brown, Green, Longmans, &amp; Roberts,</subfield> <subfield code="c">1859.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">xi, 308 p.</subfield> <subfield code="b">front. (fold. map)</subfield> <subfield code="c">20 cm.</subfield> </datafield> <datafield tag="583" ind1=" " ind2=" "> <subfield code="a">Replace;</subfield> <subfield code="z">LC copy replaced by preservation microfilm</subfield> <subfield code="5">DLC</subfield> </datafield> <datafield tag="651" ind1=" " ind2="0"> <subfield code="a">United States</subfield> <subfield code="x">Description and travel. [from old catalog]</subfield> </datafield> <datafield tag="651" ind1=" " ind2="0"> <subfield code="a">Canada</subfield> <subfield code="x">Description and travel. [from old catalog]</subfield> </datafield> <datafield tag="985" ind1=" " ind2=" "> <subfield code="g">pmosl</subfield> </datafield> <datafield tag="985" ind1=" " ind2=" "> <subfield code="e">mvp</subfield> <subfield code="f">zz01</subfield> </datafield> <datafield tag="991" ind1=" " ind2=" "> <subfield code="b">c-MicRR</subfield> <subfield code="h">Microfilm 32043 E</subfield> <subfield code="t">Copy 1</subfield> <subfield code="w">PREM</subfield> </datafield> </record></zs:recordData><zs:recordPosition>1</zs:recordPosition>

Pour une description, des services web utilisant SOAP, vous pouvez consulter la rubrique correspondante sur wikipédia. Ils sont généralement plus complexes que les services web REST.


© Daniel Lemire, 2014. Tous droits réservés.